<!-- author: xuett -->
<!-- date: 2022-09-08 09:36:19 -->
<!-- description: 文件上传 -->
<template>
  <div class="file-upload">
    <el-upload
      v-model:file-list="uploadList"
      :class="{ hideUpload: hideUploadEdit }"
      :accept="accept"
      :limit="limit"
      :auto-upload="false"
      :list-type="listType"
      :on-preview="handlePictureCardPreview"
      :before-upload="beforeAvatarUpload"
      :on-change="handleChange"
      :http-request="uploadFile"
      :on-remove="handleRemove"
      :on-exceed="handleExceed"
    >
      <el-icon v-if="listType == 'picture-card'"><Plus /></el-icon>
      <el-button v-else-if="listType == 'picture'" type="primary">选择照片</el-button>
      <el-button v-else-if="listType == 'text'" type="primary">选择文件</el-button>
    </el-upload>
    <div v-if="tipText" class="tip">{{ tipText }}</div>
    <!-- 图片预览 -->
    <el-dialog v-model="dialogVisible" title="预览">
      <img fit="contain" :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
  </div>
</template>

<script setup>
import api from "@/service/container.js";
import { ElMessage } from "element-plus";

const $props = defineProps({
  limit: {
    type: Number,
    default: 0
  },
  accept: {
    type: String,
    default: ".png,.jpg,.jpeg,.gif"
  },
  acceptList: {
    type: Array,
    default: () => []
  },
  fileSize: {
    type: Number,
    default: 20
  },
  listType: {
    type: String,
    default: "text"
  },
  openPreview: {
    type: Boolean,
    default: false
  },
  fileList: {
    type: [Array, String],
    default: () => []
  },
  tipText: {
    type: String,
    default: ""
  }
});
//文件列表
const uploadList = ref([]);
//控制显示隐藏上传组件
const hideUploadEdit = ref(false);

watch(
  () => $props.fileList,
  (newVal) => {
    if (newVal) handleFileInfo();
  }
);

//回显文件信息
const handleFileInfo = () => {
  let urlList = [];
  if (typeof $props.fileList == "string") {
    urlList = [$props.fileList];
  } else {
    urlList = $props.fileList;
  }
  uploadList.value = [];
  for (let i = 0, len = urlList.length; i < len; i++) {
    let strList = urlList[i].split("/");
    uploadList.value.push({ name: strList[strList.length - 1], progress: 100, status: "success", url: urlList[i], hasUpload: true, fileUrl: urlList[i] });
  }
  handleHideUpload();
  console.log(uploadList.value);
};

//图片上传前校验
const beforeAvatarUpload = (rawFile) => {
  const fileType = rawFile.type.substring(rawFile.type.lastIndexOf("/") + 1, rawFile.type.length);
  if ($props.acceptList.length && $props.acceptList.indexOf(fileType.toLowerCase()) == -1) {
    let str = $props.acceptList.join("、");
    ElMessage.error(`请上传${str}格式文件！`);
    return false;
  }
  if (rawFile.size / 1024 / 1024 > $props.fileSize) {
    ElMessage.error(`文件大小不能超过${$props.fileSize}M`);
    return false;
  }
  console.log(fileType);
  return true;
};

//文件状态改变
const handleChange = (uploadFile) => {
  console.log(uploadFile);
  setTimeout(() => {
    handleHideUpload();
  }, 500);
};

//手动提交
const submit = () => {
  if (!uploadList.value.length) {
    return [];
  }
  return Promise.all(
    uploadList.value.map((item) => {
      return new Promise((resolve) => {
        if (item.hasUpload) {
          //是否已上传
          resolve(item.fileUrl);
        } else {
          uploadFile(item).then((fileInfo) => {
            //上传完成，手动更改文件状态
            item.hasUpload = true;
            Object.assign(item, fileInfo, {
              progress: 100,
              status: "success"
            });
            resolve(item.fileUrl);
          });
        }
      });
    })
  );
};
//上传
const uploadFile = (options) => {
  let formData = new FormData();
  formData.append("file", options.raw);
  return new Promise((resolve) => {
    api.uploadFile(formData).then((res) => {
      resolve(res);
    });
  });
};

// 限制上传数量
const handleExceed = () => {
  ElMessage.warning(`最多上传${$props.limit}份文件`);
};

//删除上传文件
const handleRemove = (file) => {
  console.log(file);
  handleHideUpload();
};

//是否隐藏上传按钮
const handleHideUpload = () => {
  if ($props.limit) {
    hideUploadEdit.value = uploadList.value.length >= $props.limit;
  } else {
    hideUploadEdit.value = false;
  }
};

// 图片预览
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const handlePictureCardPreview = (uploadFile) => {
  if ($props.openPreview) {
    dialogImageUrl.value = uploadFile.url;
    dialogVisible.value = true;
  }
};

defineExpose({ submit });
</script>

<style scoped lang="scss">
.file-upload {
  width: 100%;
  .tip {
    color: #999;
  }
}
.hideUpload {
  :deep(.el-upload--picture-card) {
    display: none;
  }
}

:deep(.el-upload-list__item-thumbnail) {
  object-fit: cover;
}
</style>
